home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / termFastMacroWindow.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  21KB  |  1,028 lines

  1. /*
  2. **    termFastMacroWindow.c
  3. **
  4. **    Fast! macro window support routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Window border scroller. */
  13.  
  14. enum    {    GAD_SCROLLER = 10000,GAD_UP,GAD_DOWN };
  15.  
  16.     /* The arrow image height. */
  17.  
  18. #define ARROW_HEIGHT    11
  19.  
  20.     /* Pack two words into a long. */
  21.  
  22. #define PACK_ULONG(a,b)    (((ULONG)(a)) << 16 | b)
  23.  
  24.     /* Gadget extension. */
  25.  
  26. struct ButtonInfo
  27. {
  28.     struct Image    *ButtonImage;
  29.     STRPTR         ButtonCommand;
  30.     LONG         NumChars;
  31. };
  32.  
  33.     /* A private button gadget attribute. */
  34.  
  35. #define BGA_Command    (TAG_USER + 1)
  36.  
  37.     /* Private button gadget class. */
  38.  
  39. STATIC struct IClass        *ButtonClass;
  40.  
  41.     /* Window border scroller. */
  42.  
  43. STATIC struct Gadget        *Scroller,
  44.                 *UpArrow,
  45.                 *DownArrow;
  46.  
  47.     /* Width of the window border scroller. */
  48.  
  49. STATIC UWORD             RightBorderWidth;
  50.  
  51.     /* Scroller arrow imagery. */
  52.  
  53. STATIC struct Image        *UpImage,
  54.                 *DownImage;
  55.  
  56.     /* The window zoom box. */
  57.  
  58. STATIC struct IBox         WindowZoomBox = { -1,-1,-1,-1 };
  59.  
  60.     /* The fast macro buttons. */
  61.  
  62. STATIC struct Gadget        *Buttons;
  63.  
  64.     /* The first visible button and the number buttons
  65.      * visible in total.
  66.      */
  67.  
  68. STATIC LONG             ButtonTop,
  69.                  ButtonCount;
  70.  
  71.     /* RenderText():
  72.      *
  73.      *    Render the button text.
  74.      */
  75.  
  76. STATIC VOID __regargs
  77. RenderText(struct RastPort *RPort,struct GadgetInfo *GadgetInfo,struct Gadget *Gadget,LONG Len)
  78. {
  79.     UWORD    Width    = (GadgetInfo -> gi_Window -> Width - (GadgetInfo -> gi_Window -> BorderLeft + GadgetInfo -> gi_Window -> BorderRight + 4));
  80.     STRPTR    Label    = (STRPTR)Gadget -> GadgetText;
  81.     ULONG    State;
  82.     UWORD    Pen;
  83.  
  84.         /* Which state is the button in? */
  85.  
  86.     if(Gadget -> Flags & GFLG_SELECTED)
  87.     {
  88.         State    = IDS_SELECTED;
  89.         Pen    = GadgetInfo -> gi_DrInfo -> dri_Pens[FILLTEXTPEN];
  90.     }
  91.     else
  92.     {
  93.         State    = IDS_NORMAL;
  94.         Pen    = GadgetInfo -> gi_DrInfo -> dri_Pens[TEXTPEN];
  95.     }
  96.  
  97.         /* Render the frame. */
  98.  
  99.     DoMethod(Gadget -> GadgetRender,IM_DRAWFRAME,RPort,PACK_ULONG(Gadget -> LeftEdge + 2,Gadget -> TopEdge),State,GadgetInfo -> gi_DrInfo,PACK_ULONG(Width,Gadget -> Height));
  100.  
  101.         /* Set the rendering pens. */
  102.  
  103.     if(Kick30)
  104.         SetABPenDrMd(RPort,Pen,0,JAM1);
  105.     else
  106.     {
  107.         SetDrMd(RPort,JAM1);
  108.         SetAPen(RPort,Pen);
  109.     }
  110.  
  111.         /* Render the button label. */
  112.  
  113.     Move(RPort,Gadget -> LeftEdge + 4,Gadget -> TopEdge + (Gadget -> Height - GadgetInfo -> gi_DrInfo -> dri_Font -> tf_YSize) / 2 + GadgetInfo -> gi_DrInfo -> dri_Font -> tf_Baseline);
  114.     Text(RPort,Label,Len);
  115. }
  116.  
  117.     /* SetButton():
  118.      *
  119.      *    Set an aspect of the button.
  120.      */
  121.  
  122. STATIC ULONG __regargs
  123. SetButton(struct IClass *class,Object *object,struct opSet *SetInfo)
  124. {
  125.     struct ButtonInfo    *ButtonInfo = INST_DATA(class,object);
  126.     struct TagItem        *Tag,*TagList = SetInfo -> ops_AttrList;
  127.     struct RastPort        *RPort;
  128.     STRPTR             Label;
  129.     BOOLEAN             Finished = FALSE;
  130.  
  131.         /* Scan the attribute list. */
  132.  
  133.     while(Tag = NextTagItem(&TagList))
  134.     {
  135.         switch(Tag -> ti_Tag)
  136.         {
  137.                 // New command string?
  138.  
  139.             case BGA_Command:
  140.  
  141.                 ButtonInfo -> ButtonCommand = (STRPTR)Tag -> ti_Data;
  142.                 break;
  143.  
  144.                 // New label text?
  145.  
  146.             case GA_Text:
  147.  
  148.                 Label = (STRPTR)Tag -> ti_Data;
  149.  
  150.                 ((struct Gadget *)object) -> GadgetText = (struct IntuiText *)Label;
  151.  
  152.                 if(RPort = ObtainGIRPort(SetInfo -> ops_GInfo))
  153.                 {
  154.                     struct TextExtent Extent;
  155.  
  156.                     ButtonInfo -> NumChars = TextFit(RPort,Label,strlen(Label),&Extent,NULL,1,((struct Gadget *)object) -> Width - 8,32767);
  157.  
  158.                     RenderText(RPort,SetInfo -> ops_GInfo,(struct Gadget *)object,ButtonInfo -> NumChars);
  159.  
  160.                     ReleaseGIRPort(RPort);
  161.                 }
  162.  
  163.                 Finished = TRUE;
  164.  
  165.                 break;
  166.         }
  167.     }
  168.  
  169.     if(Finished)
  170.         return(TRUE);
  171.     else
  172.         return(DoSuperMethodA(class,object,(Msg)SetInfo));
  173. }
  174.  
  175.     /* RenderButton():
  176.      *
  177.      *    Render the button label.
  178.      */
  179.  
  180. STATIC ULONG __regargs
  181. RenderButton(struct IClass *class,Object *object,struct gpRender *RenderInfo)
  182. {
  183.     struct ButtonInfo *ButtonInfo = INST_DATA(class,object);
  184.  
  185.         /* No label length calculated yet? */
  186.  
  187.     if(!ButtonInfo -> NumChars)
  188.     {
  189.         STRPTR            Label = (STRPTR)((struct Gadget *)object) -> GadgetText;
  190.         struct TextExtent    Extent;
  191.  
  192.         ButtonInfo -> NumChars = TextFit(RenderInfo -> gpr_RPort,Label,strlen(Label),&Extent,NULL,1,((struct Gadget *)object) -> Width - 8,32767);
  193.     }
  194.  
  195.     RenderText(RenderInfo -> gpr_RPort,RenderInfo -> gpr_GInfo,(struct Gadget *)object,ButtonInfo -> NumChars);
  196.  
  197.     return(TRUE);
  198. }
  199.  
  200.     /* FreeButton():
  201.      *
  202.      *    Free a button gadget object.
  203.      */
  204.  
  205. STATIC ULONG __regargs
  206. FreeButton(struct IClass *class,Object *object,Msg msg)
  207. {
  208.     struct ButtonInfo *ButtonInfo = INST_DATA(class,object);
  209.  
  210.     if(ButtonInfo -> ButtonImage)
  211.         DisposeObject(ButtonInfo -> ButtonImage);
  212.  
  213.     return(DoSuperMethodA(class,object,msg));
  214. }
  215.  
  216.     /* NewButton():
  217.      *
  218.      *    Create a new button object.
  219.      */
  220.  
  221. STATIC ULONG __regargs
  222. NewButton(struct IClass *class,Object *object,struct opSet *SetMethod)
  223. {
  224.     LONG         Width,
  225.              Height;
  226.     struct TagItem    *Tag;
  227.     struct Gadget    *NewGadget = NULL;
  228.  
  229.         /* Determine object width. */
  230.  
  231.     if(Tag = FindTagItem(GA_Width,SetMethod -> ops_AttrList))
  232.         Width = Tag -> ti_Data;
  233.     else
  234.         Width = 0;
  235.  
  236.         /* Determine object height. */
  237.  
  238.     if(Tag = FindTagItem(GA_Height,SetMethod -> ops_AttrList))
  239.         Height = Tag -> ti_Data;
  240.     else
  241.         Height = 0;
  242.  
  243.         /* Proper dimensions? */
  244.  
  245.     if(Width && Height)
  246.     {
  247.         struct Image *ButtonImage;
  248.  
  249.             /* Create a button frame. */
  250.  
  251.         if(ButtonImage = NewObject(NULL,"frameiclass",
  252.             IA_Width,    Width,
  253.             IA_Height,    Height,
  254.         TAG_DONE))
  255.         {
  256.             struct TagItem    *OldTags = SetMethod -> ops_AttrList,
  257.                      NewTags[2];
  258.  
  259.                 /* Add new tag values. */
  260.  
  261.             NewTags[0] . ti_Tag    = GA_Image;
  262.             NewTags[0] . ti_Data    = (ULONG)ButtonImage;
  263.             NewTags[1] . ti_Tag    = TAG_MORE;
  264.             NewTags[1] . ti_Data    = (ULONG)OldTags;
  265.  
  266.             SetMethod -> ops_AttrList = NewTags;
  267.  
  268.                 /* Create new object. */
  269.  
  270.             if(NewGadget = (struct Gadget *)DoSuperMethodA(class,object,(Msg)SetMethod))
  271.             {
  272.                 struct ButtonInfo *ButtonInfo = INST_DATA(class,NewGadget);
  273.  
  274.                     /* Clear the number of characters displayed,
  275.                      * the first rendering call will adjust it.
  276.                      */
  277.  
  278.                 ButtonInfo -> NumChars = 0;
  279.  
  280.                     /* Install the corresponding command. */
  281.  
  282.                 if(Tag = FindTagItem(BGA_Command,OldTags))
  283.                     ButtonInfo -> ButtonCommand = (STRPTR)Tag -> ti_Data;
  284.  
  285.                     /* Remember the frame image. */
  286.  
  287.                 ButtonInfo -> ButtonImage = ButtonImage;
  288.  
  289.                     /* Restore the tags. */
  290.  
  291.                 SetMethod -> ops_AttrList = OldTags;
  292.             }
  293.             else
  294.                 DisposeObject(ButtonImage);
  295.         }
  296.     }
  297.  
  298.     return((ULONG)NewGadget);
  299. }
  300.  
  301.     /* HandleButton():
  302.      *
  303.      *    Handle button input.
  304.      */
  305.  
  306. STATIC ULONG __regargs
  307. HandleButton(struct IClass *class,Object *object,struct gpInput *InputInfo)
  308. {
  309.     ULONG             Result        = GMR_MEACTIVE;
  310.     BOOLEAN             Redraw        = FALSE,
  311.                  Final        = FALSE;
  312.     struct ButtonInfo    *ButtonInfo    = INST_DATA(class,object);
  313.     struct Gadget        *Button        = (struct Gadget *)object;
  314.  
  315.         /* Only mouse events trigger actions. */
  316.  
  317.     if(InputInfo -> gpi_IEvent -> ie_Class == IECLASS_RAWMOUSE)
  318.     {
  319.             /* Selection cancelled or no command available? */
  320.  
  321.         if(InputInfo -> gpi_IEvent -> ie_Code == MENUDOWN || !ButtonInfo -> ButtonCommand[0])
  322.         {
  323.             if(Button -> Flags & GFLG_SELECTED)
  324.             {
  325.                 Button -> Flags &= ~GFLG_SELECTED;
  326.  
  327.                 Redraw = TRUE;
  328.             }
  329.  
  330.             Result = GMR_NOREUSE;
  331.  
  332.                 /* No further actions, please. */
  333.  
  334.             Final = TRUE;
  335.         }
  336.         else
  337.         {
  338.                 /* Select button released? */
  339.  
  340.             if(InputInfo -> gpi_IEvent -> ie_Code == SELECTUP)
  341.             {
  342.                 if(Button -> Flags & GFLG_SELECTED)
  343.                 {
  344.                     *InputInfo -> gpi_Termination = 0;
  345.  
  346.                     Button -> Flags &= ~GFLG_SELECTED;
  347.  
  348.                     Redraw = TRUE;
  349.                 }
  350.                 else
  351.                     *InputInfo -> gpi_Termination = 1;
  352.  
  353.                 Result = GMR_REUSE | GMR_VERIFY;
  354.  
  355.                     /* No further actions, please. */
  356.  
  357.                 Final = TRUE;
  358.             }
  359.         }
  360.     }
  361.  
  362.         /* Change highlighting mode? */
  363.  
  364.     if(!Final)
  365.     {
  366.             /* Hit inside the boundaries? */
  367.  
  368.         if(DoMethod((Object *)ButtonInfo -> ButtonImage,IM_HITFRAME,PACK_ULONG(InputInfo -> gpi_Mouse . X,InputInfo -> gpi_Mouse . Y),PACK_ULONG(Button -> Width,Button -> Height)))
  369.         {
  370.             if(!(Button -> Flags & GFLG_SELECTED))
  371.             {
  372.                 Button -> Flags |= GFLG_SELECTED;
  373.  
  374.                 Redraw = TRUE;
  375.             }
  376.         }
  377.         else
  378.         {
  379.             if(Button -> Flags & GFLG_SELECTED)
  380.             {
  381.                 Button -> Flags &= ~GFLG_SELECTED;
  382.  
  383.                 Redraw = TRUE;
  384.             }
  385.         }
  386.     }
  387.  
  388.         /* Redraw the object? */
  389.  
  390.     if(Redraw)
  391.     {
  392.         struct RastPort *RPort;
  393.  
  394.         if(RPort = ObtainGIRPort(InputInfo -> gpi_GInfo))
  395.         {
  396.             RenderText(RPort,InputInfo -> gpi_GInfo,Button,ButtonInfo -> NumChars);
  397.  
  398.             ReleaseGIRPort(RPort);
  399.         }
  400.     }
  401.  
  402.     return(Result);
  403. }
  404.  
  405.     /* ButtonDispatch():
  406.      *
  407.      *    The button gadget class dispatcher.
  408.      */
  409.  
  410. STATIC ULONG __saveds __asm
  411. ButtonDispatch(register __a0 struct IClass *class,register __a2 Object *object,register __a1 Msg msg)
  412. {
  413.         /* Select the message method. */
  414.  
  415.     switch(msg -> MethodID)
  416.     {
  417.         case OM_NEW:
  418.  
  419.             return(NewButton(class,object,(struct opSet *)msg));
  420.  
  421.         case OM_UPDATE:
  422.         case OM_SET:
  423.  
  424.             return(SetButton(class,object,(struct opSet *)msg));
  425.  
  426.         case OM_DISPOSE:
  427.  
  428.             return(FreeButton(class,object,msg));
  429.  
  430.         case GM_RENDER:
  431.  
  432.             return(RenderButton(class,object,(struct gpRender *)msg));
  433.  
  434.         case GM_HITTEST:
  435.  
  436.             return(GMR_GADGETHIT);
  437.  
  438.         case GM_GOINACTIVE:
  439.  
  440.             return(0);
  441.  
  442.         case GM_GOACTIVE:
  443.  
  444.             return(GMR_MEACTIVE);
  445.  
  446.         case GM_HANDLEINPUT:
  447.  
  448.             return(HandleButton(class,object,(struct gpInput *)msg));
  449.  
  450.         default:
  451.  
  452.             return(DoSuperMethodA(class,object,msg));
  453.     }
  454. }
  455.  
  456.     /* FreeButtonClass(VOID):
  457.      *
  458.      *    Free private button gadget class.
  459.      */
  460.  
  461. STATIC VOID
  462. FreeButtonClass(VOID)
  463. {
  464.     if(ButtonClass)
  465.     {
  466.         FreeClass(ButtonClass);
  467.  
  468.         ButtonClass = NULL;
  469.     }
  470. }
  471.  
  472.     /* NewButtonClass(VOID):
  473.      *
  474.      *    Create private button gadget class.
  475.      */
  476.  
  477. STATIC BYTE
  478. NewButtonClass(VOID)
  479. {
  480.     if(ButtonClass = MakeClass(NULL,GADGETCLASS,NULL,sizeof(struct ButtonInfo),0))
  481.     {
  482.         ButtonClass -> cl_Dispatcher . h_Entry = (HOOKFUNC)ButtonDispatch;
  483.  
  484.         return(TRUE);
  485.     }
  486.     else
  487.         return(FALSE);
  488. }
  489.  
  490.     /* FastDeleteScroller(VOID):
  491.      *
  492.      *    Delete fast! macro window scroller.
  493.      */
  494.  
  495. STATIC VOID
  496. FastDeleteScroller(VOID)
  497. {
  498.     if(Scroller)
  499.     {
  500.         DisposeObject(Scroller);
  501.  
  502.         Scroller = NULL;
  503.     }
  504.  
  505.     if(UpArrow)
  506.     {
  507.         DisposeObject(UpArrow);
  508.  
  509.         UpArrow = NULL;
  510.     }
  511.  
  512.     if(DownArrow)
  513.     {
  514.         DisposeObject(DownArrow);
  515.  
  516.         DownArrow = NULL;
  517.     }
  518.  
  519.     if(UpImage)
  520.     {
  521.         DisposeObject(UpImage);
  522.  
  523.         UpImage = NULL;
  524.     }
  525.  
  526.     if(DownImage)
  527.     {
  528.         DisposeObject(DownImage);
  529.  
  530.         DownImage = NULL;
  531.     }
  532. }
  533.  
  534.     /* FastCreateScroller(struct Screen *Screen):
  535.      *
  536.      *    Create fast! macro window scroller.
  537.      */
  538.  
  539. STATIC BYTE __regargs
  540. FastCreateScroller(struct Screen *Screen)
  541. {
  542.     struct DrawInfo    *DrawInfo;
  543.     BYTE         Result = FALSE;
  544.  
  545.     if(DrawInfo = GetScreenDrawInfo(Screen))
  546.     {
  547.         struct Image    *SizeImage;
  548.         ULONG         SizeWidth,
  549.                  SizeHeight,
  550.                  ArrowHeight;
  551.         UWORD         SizeType;
  552.  
  553.         if(Screen -> Flags & SCREENHIRES)
  554.             SizeType = SYSISIZE_MEDRES;
  555.         else
  556.             SizeType = SYSISIZE_LOWRES;
  557.  
  558.         if(SizeImage = (struct Image *)NewObject(NULL,"sysiclass",
  559.             SYSIA_Size,    SizeType,
  560.             SYSIA_Which,    SIZEIMAGE,
  561.             SYSIA_DrawInfo,    DrawInfo,
  562.         TAG_DONE))
  563.         {
  564.             GetAttr(IA_Width,    SizeImage,&SizeWidth);
  565.             GetAttr(IA_Height,    SizeImage,&SizeHeight);
  566.  
  567.             DisposeObject(SizeImage);
  568.  
  569.             RightBorderWidth = SizeWidth;
  570.  
  571.             if(UpImage = (struct Image *)NewObject(NULL,"sysiclass",
  572.                 SYSIA_Size,    SizeType,
  573.                 SYSIA_Which,    UPIMAGE,
  574.                 SYSIA_DrawInfo,    DrawInfo,
  575.             TAG_DONE))
  576.             {
  577.                 GetAttr(IA_Height,UpImage,&ArrowHeight);
  578.  
  579.                 if(DownImage = (struct Image *)NewObject(NULL,"sysiclass",
  580.                     SYSIA_Size,    SizeType,
  581.                     SYSIA_Which,    DOWNIMAGE,
  582.                     SYSIA_DrawInfo,    DrawInfo,
  583.                 TAG_DONE))
  584.                 {
  585.                     if(Scroller = NewObject(NULL,"propgclass",
  586.                         GA_ID,        GAD_SCROLLER,
  587.  
  588.                         GA_Top,        Screen -> WBorTop + Screen -> Font -> ta_YSize + 2,
  589.                         GA_RelHeight,    -(Screen -> WBorTop + Screen -> Font -> ta_YSize + 2 + SizeHeight + 1 + 2 * ArrowHeight),
  590.                         GA_Width,    SizeWidth - 8,
  591.                         GA_RelRight,    -(SizeWidth - 5),
  592.  
  593.                         GA_Immediate,    TRUE,
  594.                         GA_FollowMouse,    TRUE,
  595.                         GA_RelVerify,    TRUE,
  596.                         GA_RightBorder,    TRUE,
  597.  
  598.                         PGA_Freedom,    FREEVERT,
  599.                         PGA_NewLook,    TRUE,
  600.                         PGA_Borderless,    TRUE,
  601.  
  602.                         PGA_Visible,    1,
  603.                         PGA_Total,    1,
  604.                     TAG_DONE))
  605.                     {
  606.                         STATIC struct TagItem ArrowMappings[] = { GA_ID,GA_ID,TAG_END };
  607.  
  608.                         if(UpArrow = NewObject(NULL,"buttongclass",
  609.                             GA_ID,        GAD_UP,
  610.  
  611.                             GA_Image,    UpImage,
  612.                             GA_RelRight,    -(SizeWidth - 1),
  613.                             GA_RelBottom,    -(SizeHeight - 1 + 2 * ArrowHeight),
  614.                             GA_Height,    ArrowHeight,
  615.                             GA_Width,    SizeWidth,
  616.                             GA_Immediate,    TRUE,
  617.                             GA_RelVerify,    TRUE,
  618.                             GA_Previous,    Scroller,
  619.                             GA_RightBorder,    TRUE,
  620.  
  621.                             ICA_TARGET,    ICTARGET_IDCMP,
  622.                             ICA_MAP,    ArrowMappings,
  623.                         TAG_DONE))
  624.                         {
  625.                             if(DownArrow = NewObject(NULL,"buttongclass",
  626.                                 GA_ID,        GAD_DOWN,
  627.  
  628.                                 GA_Image,    DownImage,
  629.                                 GA_RelRight,    -(SizeWidth - 1),
  630.                                 GA_RelBottom,    -(SizeHeight - 1 + ArrowHeight),
  631.                                 GA_Height,    ArrowHeight,
  632.                                 GA_Width,    SizeWidth,
  633.                                 GA_Immediate,    TRUE,
  634.                                 GA_RelVerify,    TRUE,
  635.                                 GA_Previous,    UpArrow,
  636.                                 GA_RightBorder,    TRUE,
  637.  
  638.                                 ICA_TARGET,    ICTARGET_IDCMP,
  639.                                 ICA_MAP,    ArrowMappings,
  640.                             TAG_DONE))
  641.                                 Result = TRUE;
  642.                         }
  643.                     }
  644.                 }
  645.             }
  646.         }
  647.  
  648.         FreeScreenDrawInfo(Screen,DrawInfo);
  649.     }
  650.  
  651.     return(Result);
  652. }
  653.  
  654.     /* RefreshFastWindow(WORD FastWindowHeight):
  655.      *
  656.      *    Refresh the contents of the fast! macro window.
  657.      */
  658.  
  659. VOID __regargs
  660. RefreshFastWindow(BYTE FullRefresh)
  661. {
  662.     if(FastWindow)
  663.     {
  664.         LONG Count = (FastWindow -> Height - (FastWindow -> BorderTop + FastWindow -> BorderBottom + 1)) / (2 + UserFontHeight + 2 + 1);
  665.  
  666.         if(FullRefresh)
  667.             ButtonCount = 0;
  668.  
  669.         if(Count == ButtonCount && Buttons)
  670.         {
  671.             LONG NewTop;
  672.  
  673.             if(!GetAttr(PGA_Top,Scroller,(ULONG *)&NewTop))
  674.                 NewTop = 0;
  675.  
  676.             if(NewTop != ButtonTop)
  677.             {
  678.                 ButtonTop = NewTop;
  679.  
  680.                 Count = 0;
  681.  
  682.                 if(FastMacroList . lh_Head -> ln_Succ)
  683.                 {
  684.                     struct DrawInfo *DrawInfo;
  685.  
  686.                     if(DrawInfo = GetScreenDrawInfo(FastWindow -> WScreen))
  687.                     {
  688.                         struct MacroNode    *Node    = (struct MacroNode *)GetListNode(ButtonTop,&FastMacroList);
  689.                         struct Gadget        *Button    = Buttons;
  690.  
  691.                         while(Count < ButtonCount && Node -> mn_Succ)
  692.                         {
  693.                             SetGadgetAttrs(Button,FastWindow,NULL,
  694.                                 GA_Text,    Node -> mn_Macro,
  695.                                 BGA_Command,    Node -> mn_Code,
  696.                             TAG_DONE);
  697.  
  698.                             Count++;
  699.  
  700.                             Button = Button -> NextGadget;
  701.  
  702.                             Node = Node -> mn_Succ;
  703.                         }
  704.  
  705.                         FreeScreenDrawInfo(FastWindow -> WScreen,DrawInfo);
  706.                     }
  707.                 }
  708.             }
  709.         }
  710.         else
  711.         {
  712.             LONG Top = FastWindow -> BorderTop + 1;
  713.  
  714.             if(Buttons)
  715.             {
  716.                 struct Gadget    *Next = Buttons,
  717.                         *Button;
  718.  
  719.                 RemoveGList(FastWindow,Buttons,-1);
  720.  
  721.                 while(Button = Next)
  722.                 {
  723.                     Next = Button -> NextGadget;
  724.  
  725.                     DisposeObject(Button);
  726.                 }
  727.  
  728.                 Buttons = NULL;
  729.             }
  730.  
  731.             ButtonCount = Count;
  732.  
  733.             if(ButtonTop >= FastMacroCount)
  734.                 ButtonTop = FastMacroCount - ButtonCount;
  735.             else
  736.             {
  737.                 if(ButtonTop + ButtonCount > FastMacroCount)
  738.                     ButtonTop = FastMacroCount - ButtonCount;
  739.             }
  740.  
  741.             if(ButtonTop < 0)
  742.                 ButtonTop = 0;
  743.  
  744.             Count = 0;
  745.  
  746.             if(FastMacroList . lh_Head -> ln_Succ)
  747.             {
  748.                 struct DrawInfo *DrawInfo;
  749.  
  750.                 if(DrawInfo = GetScreenDrawInfo(FastWindow -> WScreen))
  751.                 {
  752.                     struct MacroNode    *Node        = (struct MacroNode *)GetListNode(ButtonTop,&FastMacroList);
  753.                     LONG             Width        = FastWindow -> Width - (FastWindow -> BorderLeft + FastWindow -> BorderRight);
  754.                     struct Gadget        *Previous    = NULL,
  755.                                 *Button;
  756.  
  757.                     while(Count < ButtonCount && Node -> mn_Succ)
  758.                     {
  759.                         if(Button = NewObject(ButtonClass,NULL,
  760.                             GA_ID,        Count,
  761.  
  762.                             GA_Top,        Top,
  763.                             GA_Left,    FastWindow -> BorderLeft,
  764.  
  765.                             GA_Width,    Width,
  766.                             GA_Height,    (2 + UserFontHeight + 2),
  767.                             GA_RelVerify,    TRUE,
  768.  
  769.                             GA_DrawInfo,    DrawInfo,
  770.                             GA_Text,    Node -> mn_Macro,
  771.                             BGA_Command,    Node -> mn_Code,
  772.  
  773.                             Previous ? GA_Previous : TAG_IGNORE,Previous,
  774.                         TAG_DONE))
  775.                         {
  776.                             Top += 2 + UserFontHeight + 2 + 1;
  777.  
  778.                             Count++;
  779.  
  780.                             Previous = Button;
  781.  
  782.                             if(!Buttons)
  783.                                 Buttons = Button;
  784.  
  785.                             Node = Node -> mn_Succ;
  786.                         }
  787.                     }
  788.  
  789.                     FreeScreenDrawInfo(FastWindow -> WScreen,DrawInfo);
  790.                 }
  791.             }
  792.  
  793.             if(Count)
  794.             {
  795.                 AddGList(FastWindow,Buttons,-1,-1,NULL);
  796.  
  797.                 RefreshGList(Buttons,FastWindow,NULL,-1);
  798.             }
  799.  
  800.             if(Top < FastWindow -> Height - (FastWindow -> BorderBottom + 1))
  801.             {
  802.                 SetAPen(FastWindow -> RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
  803.  
  804.                 RectFill(FastWindow -> RPort,FastWindow -> BorderLeft,Top,FastWindow -> Width - (FastWindow -> BorderRight + 1),FastWindow -> Height - (FastWindow -> BorderBottom + 1));
  805.             }
  806.  
  807.             SetGadgetAttrs(Scroller,FastWindow,NULL,
  808.                 PGA_Top,    ButtonTop,
  809.                 PGA_Visible,    ButtonCount,
  810.                 PGA_Total,    FastMacroCount,
  811.             TAG_DONE);
  812.         }
  813.     }
  814. }
  815.  
  816.     /* CloseFastWindow():
  817.      *
  818.      *    Close the fast! macro window and free the associated resources.
  819.      */
  820.  
  821. VOID
  822. CloseFastWindow()
  823. {
  824.     CheckItem(MEN_FAST_MACROS_WINDOW,FALSE);
  825.  
  826.     if(Buttons)
  827.     {
  828.         struct Gadget    *Next = Buttons,
  829.                 *Button;
  830.  
  831.         RemoveGList(FastWindow,Buttons,-1);
  832.  
  833.         while(Button = Next)
  834.         {
  835.             Next = Button -> NextGadget;
  836.  
  837.             DisposeObject(Button);
  838.         }
  839.  
  840.         Buttons = NULL;
  841.     }
  842.  
  843.     if(FastWindow)
  844.     {
  845.         PutWindowInfo(WINDOW_FAST,FastWindow -> LeftEdge,FastWindow -> TopEdge,FastWindow -> Width,FastWindow -> Height);
  846.  
  847.         ClearMenuStrip(FastWindow);
  848.         CloseWindowSafely(FastWindow);
  849.  
  850.         FastWindow = NULL;
  851.     }
  852.  
  853.     FreeButtonClass();
  854. }
  855.  
  856.     /* OpenFastWindow():
  857.      *
  858.      *    Open the fast! macro window.
  859.      */
  860.  
  861. BYTE
  862. OpenFastWindow()
  863. {
  864.     if(FastWindow)
  865.         return(TRUE);
  866.  
  867.     if(NewButtonClass())
  868.     {
  869.         if(FastCreateScroller(Window -> WScreen))
  870.         {
  871.             LONG    Left    = 0,
  872.                 Top    = 0,
  873.                 Width    = Window -> WScreen -> WBorLeft + 2 + SZ_GetLen("####################") + 2 + RightBorderWidth,
  874.                 Height    = 0;
  875.  
  876.             GetWindowInfo(WINDOW_FAST,&Left,&Top,&Width,&Height,NULL,Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 1 + 1 + 10 * (2 + UserFontHeight + 2 + 1) + Window -> WScreen -> WBorBottom);
  877.  
  878.             if(WindowZoomBox . Left == -1)
  879.             {
  880.                 WindowZoomBox . Left    = 0;
  881.                 WindowZoomBox . Top    = 0;
  882.                 WindowZoomBox . Width    = Width;
  883.                 WindowZoomBox . Height    = Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 1;
  884.             }
  885.  
  886.             if(FastWindow = OpenWindowTags(NULL,
  887.                 WA_Width,        Width,
  888.                 WA_Height,        Height,
  889.  
  890.                 WA_Left,        Left,
  891.                 WA_Top,            Top,
  892.  
  893.                 WA_DragBar,        TRUE,
  894.                 WA_DepthGadget,        TRUE,
  895.                 WA_CloseGadget,        TRUE,
  896.                 WA_RMBTrap,        TRUE,
  897.                 WA_Zoom,        &WindowZoomBox,
  898.                 WA_NoCareRefresh,    TRUE,
  899.                 WA_BackFill,        &BackfillHook,
  900.                 WA_MenuHelp,        TRUE,
  901.  
  902.                 WA_SizeGadget,        TRUE,
  903.  
  904.                 WA_MinWidth,        Width,
  905.                 WA_MaxWidth,        Width,
  906.  
  907.                 WA_MinHeight,        Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 1 + 2 * (2 + UserFontHeight + 2 + 1) + 1 + Window -> WScreen -> WBorBottom,
  908.                 WA_MaxHeight,        Window -> WScreen -> Height,
  909.  
  910.                 WA_Title,        LocaleString(MSG_FASTMACROS_FAST_MACROS_TXT),
  911.  
  912.                 WA_NewLookMenus,    TRUE,
  913.                 WA_Gadgets,        Scroller,
  914.  
  915.                 WA_CustomScreen,    Window -> WScreen,
  916.  
  917.                 AmigaGlyph ? WA_AmigaKey  : TAG_IGNORE, AmigaGlyph,
  918.                 CheckGlyph ? WA_Checkmark : TAG_IGNORE, CheckGlyph,
  919.             TAG_DONE))
  920.             {
  921.                 ButtonTop    = 0;
  922.                 ButtonCount    = -1;
  923.  
  924.                 FastWindow -> UserPort = Window -> UserPort;
  925.  
  926.                 ModifyIDCMP(FastWindow,Window -> IDCMPFlags | IDCMP_IDCMPUPDATE | IDCMP_SIZEVERIFY);
  927.  
  928.                 SetMenuStrip(FastWindow,Menu);
  929.  
  930.                 FastWindow -> Flags &= ~WFLG_RMBTRAP;
  931.  
  932.                 RefreshFastWindow(TRUE);
  933.  
  934.                 CheckItem(MEN_FAST_MACROS_WINDOW,TRUE);
  935.  
  936.                 return(TRUE);
  937.             }
  938.  
  939.             FastDeleteScroller();
  940.         }
  941.  
  942.         FreeButtonClass();
  943.     }
  944.  
  945.     return(FALSE);
  946. }
  947.  
  948.     /* HandleFastWindowGadget(ULONG IClass,LONG ICode,LONG GadgetID):
  949.      *
  950.      *    Process fast! macro window input.
  951.      */
  952.  
  953. VOID __regargs
  954. HandleFastWindowGadget(ULONG IClass,LONG ICode,LONG GadgetID)
  955. {
  956.     STATIC BYTE Scrolling = FALSE;
  957.  
  958.     switch(IClass)
  959.     {
  960.         case IDCMP_GADGETUP:
  961.  
  962.             if(GadgetID == GAD_SCROLLER)
  963.                 Scrolling = FALSE;
  964.             else
  965.             {
  966.                 if(GadgetID < GAD_SCROLLER && !ICode)
  967.                 {
  968.                     struct MacroNode *Node;
  969.  
  970.                     if(Node = (struct MacroNode *)GetListNode(GadgetID + ButtonTop,&FastMacroList))
  971.                     {
  972.                         if(Node -> mn_Code[0])
  973.                             SerialCommand(Node -> mn_Code);
  974.                     }
  975.                 }
  976.             }
  977.  
  978.             break;
  979.  
  980.         case IDCMP_GADGETDOWN:
  981.  
  982.             if(GadgetID == GAD_SCROLLER)
  983.             {
  984.                 Scrolling = TRUE;
  985.  
  986.                 RefreshFastWindow(FALSE);
  987.             }
  988.  
  989.             break;
  990.  
  991.         case IDCMP_MOUSEMOVE:
  992.  
  993.             if(Scrolling)
  994.                 RefreshFastWindow(FALSE);
  995.  
  996.             break;
  997.  
  998.         case IDCMP_IDCMPUPDATE:
  999.  
  1000.             switch(GadgetID)
  1001.             {
  1002.                 case GAD_UP:    if(ButtonTop)
  1003.                         {
  1004.                             SetGadgetAttrs(Scroller,FastWindow,NULL,
  1005.                                 PGA_Top,ButtonTop - 1,
  1006.                             TAG_DONE);
  1007.  
  1008.                             RefreshFastWindow(FALSE);
  1009.                         }
  1010.  
  1011.                         break;
  1012.  
  1013.                 case GAD_DOWN:    if(ButtonTop + ButtonCount < FastMacroCount)
  1014.                         {
  1015.                             SetGadgetAttrs(Scroller,FastWindow,NULL,
  1016.                                 PGA_Top,ButtonTop + 1,
  1017.                             TAG_DONE);
  1018.  
  1019.                             RefreshFastWindow(FALSE);
  1020.                         }
  1021.  
  1022.                         break;
  1023.             }
  1024.  
  1025.             break;
  1026.     }
  1027. }
  1028.